﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Zero.Core
{
    public class DataHelper
    {
        //Fields
        private static Regex keyReg = new Regex("[^a-zA-Z]", RegexOptions.Compiled);

        //Methods
        private static bool CheckStruct(Type type)
        {
            if (!type.IsValueType||type.IsEnum)
            {
                return false;
            }
            return (!type.IsPrimitive && !type.IsSerializable);
        }

        public static object Clone(object obj)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, obj);
                stream.Position = 0;
                return formatter.Deserialize(stream);
            }
        }

        public static IEnumerable<TTarget> ConvertList<TSource, TTarget>(List<TSource> list)
        {
            List<TTarget> list2 = new List<TTarget>();
            foreach (TSource local in list)
            {
                list2.Add((TTarget)ConvertValue(typeof(TTarget), local));
            }
            return list2;
        }

        public static TResult ConvertValue<TResult>(object value)
        {
            if (Convert.IsDBNull(value) || (value == null))
            {
                return default(TResult);
            }
            object obj2 = ConvertValue(typeof(TResult), value);
            if (obj2 == null)
            {
                return default(TResult);
            }
            return (TResult)obj2;
        }

        public static object ConvertValue(Type type, object value)
        {
            if (Convert.IsDBNull(value)||(value==null))
            {
                return null;
            }

            if (CheckStruct(type))
            {
                string data = value.ToString();
                return SerializationManager.Deserialize(type, data);
            }
            Type type2 = value.GetType();
            if (type==type2)
            {
                return value;
            }
            if ( ((type==typeof(Guid)) || (type==typeof(Guid?))) && (type2 == typeof(string)))
            {
                if (string.IsNullOrEmpty(value.ToString()))
                {
                    return null;
                }
                return new Guid(value.ToString());
            }
            if (((type == typeof(DateTime)) || (type == typeof(DateTime?))) && (type2 == typeof(string)))
            {
                if (string.IsNullOrEmpty(value.ToString()))
                {
                    return null;
                }
                return Convert.ToDateTime(value);
            }

            if (type.IsEnum)
            {
                try
                {
                    return Enum.Parse(type, value.ToString(), true);
                }
                catch
                {
                    return Enum.ToObject(type, value);
                }
            }

            if ((type == typeof(bool)) || (type == typeof(bool?)))
            {
                bool result = false;
                if (bool.TryParse(value.ToString(), out result))
                {
                    return result;
                }
                if (string.IsNullOrEmpty(value.ToString()))
                {
                    return false;
                }
                return true;
            }

            if (type.IsGenericType)
            {
                type = type.GetGenericArguments()[0];
            }
            return Convert.ChangeType(value, type);

            
        }

    }
}
